from .student_operations import StudentOperations
from .course_operations import CourseOperations
from .schedule_operations import ScheduleOperations

class CourseManagementSystem:
    def __init__(self, students, classes, courses, grades):
        self.student_ops = StudentOperations(students, grades)
        self.course_ops = CourseOperations(courses,students)
        self.schedule_ops = ScheduleOperations(students, courses)
        self.classes = classes
        self.grades = grades
    def display_all_students(self):
        return self.student_ops.get_all_students()
    
    def display_all_courses(self):
        return self.course_ops.get_all_courses()
    
    def display_student_information(self, username):
        return self.student_ops.get_student_information(username)
    
    def display_course_information(self, course_id):
        return self.course_ops.get_course_information(course_id)
    
    def display_student_grades(self, username):
        return self.student_ops.get_student_grades(username)
    
    def display_course_students(self, course_id):
        return self.course_ops.get_course_students(course_id)
    
    def check_schedule_conflicts(self, username):
        return self.schedule_ops.check_conflicts(username)
    
    def display_course_ranking(self, course_id):
        ranking = self.student_ops.get_course_ranking(course_id)
        if ranking is None:
            return None
        if not ranking:
            return f'not ranking'
        ranked = [(i+1, student['username'], 
        student['average'], 
        student['scores']) 
        for i, student in enumerate(ranking)]
    
        return ranked

    def display_name_sorted(self,by='name'):
        name_sorted_students = self.student_ops.sort_students_name(by)
        sorted_result = []
        for i,student in enumerate(name_sorted_students,1):
            sorted_result.append({
            "index":i,
            "full name":student['fullName'],
            "username":student['username'],
            "age":student['age'],
            "school":student['school'],
            "interests":student['interests']})
        return sorted_result
    
    def validate_new_course(self, new_course_data):
        if any(c['courseId'] == new_course_data['courseId'] for c in self.course_ops.courses):
            raise ValueError(f"课程ID {new_course_data['courseId']} 已存在")

        conflicts = self.schedule_ops.check_new_course_conflict(new_course_data)
        if conflicts:
            conflict_msgs = []
            for conflict in conflicts:
                if conflict['type'] == 'room':
                    msg = (f"Conflict: new course {conflict['new_course']} and current course {conflict['existing_course']}\n"
                          f"Classroom confliction: {conflict['room']}\n"
                          f"Time confliction: {', '.join(conflict['conflict_days'])} "
                          f"{conflict['existing_time']} vs {conflict['new_time']}")
                    conflict_msgs.append(msg)
            raise ValueError("\n".join(conflict_msgs))

        return True
    
    def search_suggestions(self, search_type, prefix):
        prefix = prefix.lower()
        if search_type == 'course':
            return [
            {
                'display': f"{course['courseId']} ({course['department']})",
                'id': course['courseId']
            }
            for course in self.course_ops.courses 
            if (course['courseId'].lower().startswith(prefix) or
                course['department'].lower().startswith(prefix))
            ][:5]
        elif search_type == 'student':
            return [
                {'display': student['fullName'], 'id': student['username']}
                for student in self.student_ops.students 
                if student['fullName'].lower().startswith(prefix)
            ][:5]
        return []


    def enroll_student(self, student_username, course_id):
        try:
            meets_prereqs, missing = self.course_ops.validate_prerequisites(student_username, course_id)
            if not meets_prereqs:
                return f"❌ Course enrollment failed:Lack of prerequisite courses {', '.join(missing)}"

            course = next((c for c in self.course_ops.courses if c['courseId'] == course_id), None)
            if not course:
                return "❌ Error:The course does not exist"

            student = next((s for s in self.student_ops.students if s['username'] == student_username), None)
            if not student:
                return "❌ Error:Student does not exist"


            if course_id in student['followed_courses']:
                return f"ℹ️ prompt:Student {student_username} Have taken the course"

            conflicts = self.schedule_ops.check_student_schedule_conflict(student, course)
            if conflicts:
                conflict_msg = self._format_conflict_message(conflicts, course)
                return conflict_msg
            student['followed_courses'].append(course_id)
            return f"✅ Successfully add {course_id} for {student_username}"
        except Exception as e:
            return f"❌ System error:{str(e)}"
            
    def _format_conflict_message(self, conflicts, new_course):
        new_title = new_course.get('title', new_course['courseId'])
        msg = [
            "⚠️ Time conflict detection results:",
            "----------------------------------------",
            f"Try adding a course: {new_title} ({new_course['courseId']})",
            f"Class time: {', '.join(new_course['schedule']['days'])} {new_course['schedule']['time']}",
            "----------------------------------------",
            "There is a time conflict with the following courses:"
        ]

        for conflict in conflicts:
            msg.extend([
                f"----------------------------------------",
                f"Conflict Course: {conflict['existing_title']} ({conflict['existing_course']})",
                f"Conflict Time: {', '.join(conflict['conflict_days'])}",
                f"Original course time: {conflict['existing_time']}",
                f"New course time: {conflict['new_time']}",
            ])

        msg.extend([
            "----------------------------------------",
            "Please select a solution below:",
            "1. Select a different time period",
            "2. Withdraw from conflicting courses",
            "3. Contact the Registrar's Office to request special course selection",
            "----------------------------------------"
        ])

        return "\n".join(msg)